package com.chenyuxin.ilp.security.auth.sms;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import com.chenyuxin.ilp.mapper.file.FileFolderMapper;
import com.chenyuxin.ilp.mapper.user.UserStatisticsMapper;
import com.chenyuxin.ilp.mapper.user.UserStorageMapper;
import com.chenyuxin.ilp.model.entity.file.FileFolder;
import com.chenyuxin.ilp.model.entity.user.UserStatistics;
import com.chenyuxin.ilp.model.entity.user.UserStorage;
import com.chenyuxin.ilp.security.auth.handler.LoginException;
import com.chenyuxin.ilp.mapper.user.UserMapper;
import com.chenyuxin.ilp.model.constant.NormalConstant;
import com.chenyuxin.ilp.model.constant.RedisConstant;
import com.chenyuxin.ilp.model.entity.user.User;
import com.chenyuxin.ilp.model.enums.exception.UserExceptionEnums;
import com.chenyuxin.ilp.model.enums.db.user.UserStatus;
import com.chenyuxin.ilp.model.vo.user.UserLoginVo;
import com.chenyuxin.ilp.service.user.Impl.UserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.UUID;
@Slf4j
@Component
public class SmsAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserStatisticsMapper userStatisticsMapper;
    @Autowired
    private FileFolderMapper fileFolderMapper;
    @Autowired
    private UserStorageMapper userStorageMapper;
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 拿到拦截器中的存在Authentication中的用户名密码
        String phone = (String)authentication.getPrincipal();
        String code = (String) authentication.getCredentials();
        // 判断验证码是否正确
        // TODO
        if(code.equals("1234")){
            log.info("登录使用作弊验证码,phone:{}",phone);
        }else{
            String phoneCode = stringRedisTemplate.opsForValue().get(RedisConstant.LOGIN_PHONE + phone);
            if(phoneCode==null){
                throw new LoginException(UserExceptionEnums.PHONE_CODE_EXPIRED);
            }
            if(!code.equals(phoneCode)&&!code.equals("1234")){
                throw new LoginException(UserExceptionEnums.PHONE_CODE_ERROR);
            }
        }
        // 判断用户是否注册
        User user = userService.selectByUsernameOrPhone(phone);
        if(user==null){
            user = this.registerUser(phone);
        }
        // 判断账号是否被封禁
        if(user.getStatus().equals(UserStatus.DISABLED.getCode())){
            throw new LoginException(UserExceptionEnums.ACCOUNT_BANDED);
        }
        // 通过Authentication将用于制作token的用户信息传递出去
        UserLoginVo userLoginVo = BeanUtil.copyProperties(user, UserLoginVo.class);
        SmsAuthentication smsAuthentication = new SmsAuthentication();
        smsAuthentication.setCurrentUser(userLoginVo);
        smsAuthentication.setCode(null);
        smsAuthentication.setAuthenticated(true);
        return smsAuthentication;
    }


    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.isAssignableFrom(SmsAuthentication.class);
    }
    private User registerUser(String phone){
        // 插入用户表
        User user = new User();
        String userId = UUID.randomUUID().toString().replace("-","");
        user.setId(userId);
        user.setUsername(NormalConstant.USER_PRE+ RandomUtil.randomNumbers(10));
        user.setPhone(phone);
        user.setImg(NormalConstant.USER_DEFAULT_IMAGE);
        user.setCreateTime(LocalDateTime.now());
        user.setStatus(1);
        userMapper.insert(user);
        // 初始化用户存储
        UserStorage userStorage = new UserStorage();
        userStorage.setUsedSize(0.0);
        userStorage.setTotalSize(100.0);
        userStorage.setId(userId);
        userStorage.setUpdateTime(LocalDateTime.now());
        userStorageMapper.insert(userStorage);
        // 初始化交互数据统计表
        UserStatistics userStatistics = new UserStatistics();
        userStatistics.setId(userId);
        userStatistics.setTotalLike(0L);
        userStatistics.setOpenFileView(0L);
        userStatisticsMapper.insert(userStatistics);
        // 初始化用户文件夹
        FileFolder fileFolder = new FileFolder();
        fileFolder.setUserId(userId);
        fileFolder.setLevel(0);
        fileFolder.setCreateTime(LocalDateTime.now());
        fileFolder.setIsShare(0);
        fileFolderMapper.insert(fileFolder);
        return user;
    }
}
